/**
* 版权声明：厦门睿商网络科技有限公司 版权所有 违者必究
* 日    期：2020-02-17
*/
package com.rzico.account.service;

import com.alibaba.fastjson.JSON;
import com.rzico.account.entity.Payment;
import com.rzico.account.entity.Receivable;
import com.rzico.account.mapper.PaymentMapper;
import com.rzico.account.model.Attach;
import com.rzico.base.BaseMapper;
import com.rzico.base.CommResult;
import com.rzico.base.impl.BaseServiceImpl;
import com.rzico.account.entity.Refunds;
import com.rzico.basics.entity.Enterprise;
import com.rzico.basics.service.EnterpriseService;
import com.rzico.core.entity.SysMch;
import com.rzico.core.entity.SysPlugin;
import com.rzico.core.plugin.AuthPlugin;
import com.rzico.core.plugin.PaymentPlugin;
import com.rzico.core.service.SysMchService;
import com.rzico.core.service.SysPluginService;
import com.rzico.exception.CustomException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import com.rzico.account.mapper.RefundsMapper;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * <pre>
 * 退款单业务类
 * </pre>
 *
 * @author Rzico Boot
 * @version 1.0
 */
@Service
public class RefundsService extends BaseServiceImpl<Refunds, String> {
    protected Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private RefundsMapper refundsMapper;

    @Autowired
    private PaymentMapper paymentMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired @Lazy
    private CardBillService cardBillService;

    @Autowired @Lazy
    private PointService pointService;

    @Autowired @Lazy
    private MatchPointService matchPointService;

    @Autowired @Lazy
    private DepositService depositService;

    @Autowired @Lazy
    private EnterpriseService enterpriseService;

    @Autowired @Lazy
    private ReceivableService receivableService;

    @Autowired @Lazy
    private SysPluginService sysPluginService;

    @Autowired
    private SysMchService sysMchService;

    @Override
    public BaseMapper<Refunds, String> getMapper() {
        return refundsMapper;
    }


    public List<Refunds> getItemList(Long orderType,Long orderId) {
        Map<String,Object> params = new HashMap<>();
        params.put("orderId",orderId);
        params.put("orderType",orderType);
        return selectList(params);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteByIds(Object [] ids) {
        int rw = 0;
        for (Object id:ids) {
            Refunds refunds = selectByPrimaryKey(id);
            refunds.setDeleted(true);
            rw = rw + super.updateByPrimaryKeySelective(refunds);
        }
        return rw;
    }

    public Refunds findBySn(String sn){
        Map<String,Object> params = new HashMap<>();
        params.put("sn",sn);
        List<Refunds> refunds = super.selectList(params);
        if (refunds.size()>0) {
            return refunds.get(0);
        } else {
            return null;
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void submit(Long id) throws Exception {

        Refunds refunds = findById(id);
        if (refunds!=null) {

            Enterprise enterprise = enterpriseService.findById(refunds.getEnterpriseId());

            SysMch sysMch = sysMchService.selectByPrimaryKey(enterprise.getMchId());
            if (sysMch.getMchType().equals(2)) {
                //特约商户,服务商代收
                enterprise = enterpriseService.findByMch(sysMch.getIsvId());
            }

            SysPlugin sysPlugin = sysPluginService.findByPlugin(enterprise.getMchId(),refunds.getPaymentPluginId());
            if (sysPlugin==null) {
                refunds.setTranSn("没有安装插件");
                updateByPrimaryKeySelective(refunds);
                return;
            }

            Payment payment = paymentMapper.selectByPrimaryKey(refunds.getPaymentId());

            PaymentPlugin paymentPlugin = sysPluginService.getPaymentPlugin(refunds.getPaymentPluginId());

            Map<String,Object> data = paymentPlugin.refund(sysPlugin,refunds.getSn(),payment.getSn(),payment.getAmount(),refunds.getAmount(),null);
            if ("0000".equals(data.get("return_code").toString())) {
                //提交成功后，等待查询结果
                refunds.setTranSn(String.valueOf(data.get("tranSn")));
                refunds.setStatus(Refunds.STATUS_SUCCESS);
                updateByPrimaryKeySelective(refunds);
            } else {
                throw new CustomException(data.get("error_msg").toString());
            }

        }

    }

    public void query(Long id) throws Exception {

        Refunds refunds = selectByPrimaryKey(id);

        PaymentPlugin paymentPlugin = sysPluginService.getPaymentPlugin(refunds.getPaymentPluginId());

        Enterprise enterprise = enterpriseService.findById(refunds.getEnterpriseId());


        SysMch sysMch = sysMchService.selectByPrimaryKey(enterprise.getMchId());
        if (sysMch.getMchType().equals(2)) {
            //特约商户,服务商代收
            enterprise = enterpriseService.findByMch(sysMch.getIsvId());
        }


        SysPlugin sysPlugin = sysPluginService.findByPlugin(enterprise.getMchId(),refunds.getPaymentPluginId());
        if (sysPlugin==null) {
            return;
        }
        Map<String,Object> resultMap = paymentPlugin.refundQuery(sysPlugin,refunds.getSn(),refunds.getTranSn(),null);

        if ("0000".equals(resultMap.get("return_code").toString())) {
            try {
                handle(refunds.getSn(),resultMap.get("tranSn").toString());
            } catch (Exception e) {
                logger.error(e.getMessage());
            }
        } else {
            if (!"0001".equals(resultMap.get("return_code").toString()) && !"9999".equals(resultMap.get("return_code").toString())) {
                //refunds.setTranSn(String.valueOf(resultMap.get("error_msg")));
                refunds.setStatus(Refunds.STATUS_FAILURE);
                updateByPrimaryKeySelective(refunds);
            }
        }

    }

    public void handle(String sn,String tranSn) throws Exception {
        Refunds refunds = findBySn(sn);
        //if (refunds.getStatus().equals(Refunds.STATUS_SUCCESS)) {
            refunds.setStatus(Refunds.STATUS_REFUNDED);
            refunds.setTranSn(tranSn);
            refundsMapper.updateByPrimaryKeySelective(refunds);
        //}

        //通过MQ异步通知支付成功
        if (refunds.getAttach()!=null) {
            Attach attachQueue = refunds.decodeAttach();
            attachQueue.setCode("0000");
            Message message = MessageBuilder
                    .withBody(JSON.toJSONString(attachQueue).getBytes())
                    .setContentType(MessageProperties.CONTENT_TYPE_JSON)
                    .build();
            CorrelationData correlationData = new CorrelationData();
            correlationData.setId(UUID.randomUUID().toString());
            rabbitTemplate.convertAndSend("directExchange",attachQueue.getQueue()+".key", message, correlationData);
        }

    }

    public void failure(String sn) throws Exception {
        Refunds refunds = findBySn(sn);
        if (refunds.getStatus().equals(Refunds.STATUS_SUCCESS)) {
            refunds.setStatus(Refunds.STATUS_FAILURE);
            refundsMapper.updateByPrimaryKeySelective(refunds);
        }
        //通过MQ异步通知支付成功
        if (refunds.getAttach()!=null) {
            Attach attachQueue = refunds.decodeAttach();
            attachQueue.setCode("0003");
            Message message = MessageBuilder
                    .withBody(JSON.toJSONString(attachQueue).getBytes())
                    .setContentType(MessageProperties.CONTENT_TYPE_JSON)
                    .build();
            CorrelationData correlationData = new CorrelationData();
            correlationData.setId(UUID.randomUUID().toString());
            rabbitTemplate.convertAndSend("directExchange",attachQueue.getQueue()+".key", message, correlationData);
        }

    }

    //退款（只用于系统内支付方式）
    @Transactional(rollbackFor = Exception.class)
    public void execRefunds(Refunds refunds) {
        if ("cardPayPlugin".equals(refunds.getPaymentPluginId())) {
            cardBillService.refunds(refunds);
        } else
        if ("pointPayPlugin".equals(refunds.getPaymentPluginId())) {
            pointService.refunds(refunds);
        } else
        if ("matchPtPayPlugin".equals(refunds.getPaymentPluginId())) {
            matchPointService.refunds(refunds);
        } else
        if ("balancePayPlugin".equals(refunds.getPaymentPluginId())) {
            depositService.refunds(refunds);
        } else
        if ("cashPayPlugin".equals(refunds.getPaymentPluginId())) {
            refunds.setStatus(Refunds.STATUS_REFUNDED);
            refunds.setRefundsDate(new Date());
            updateByPrimaryKeySelective(refunds);
        }  else
        if ("paperPayPlugin".equals(refunds.getPaymentPluginId())) {
            refunds.setStatus(Refunds.STATUS_REFUNDED);
            refunds.setRefundsDate(new Date());
            updateByPrimaryKeySelective(refunds);
        }  else
        if ("bankPayPlugin".equals(refunds.getPaymentPluginId())) {
            refunds.setStatus(Refunds.STATUS_REFUNDED);
            refunds.setRefundsDate(new Date());
            updateByPrimaryKeySelective(refunds);
//        }  else
//        if ("debtPayPlugin".equals(refunds.getPaymentPluginId())) {
//            refunds.setStatus(Refunds.STATUS_SUCCESS);
//            refunds.setRefundsDate(new Date());
//            updateByPrimaryKeySelective(refunds);
//            //同时生成应退款
//
//            Receivable receivable = new Receivable();
//            receivable.setAmount(BigDecimal.ZERO.subtract(refunds.getAmount()));
//            receivable.setAmountPaid(BigDecimal.ZERO);
//            receivable.setType(0);
//
//            //订单未付款
//            receivable.setStatus(0);
//
//            receivable.setDeleted(false);
//            receivable.setMemberId(refunds.getMemberId());
//            receivable.setEnterpriseId(refunds.getEnterpriseId());
//            receivable.setOrderId(refunds.getOrderId());
//            receivableService.insertUseGeneratedKeys(receivable);
//
        }
//        if (refunds.getStatus().equals(Refunds.STATUS_REFUNDED) || refunds.getStatus().equals(Refunds.STATUS_SUCCESS)) {
//            try {
//                //退知退款完成
//                handle(refunds.getSn(), null);
//            } catch (Exception e) {
//                throw new CustomException(e.getMessage());
//            }
//        }

    }

}
